/* 利用串口屏配合操作系统提高交互控制 */
#include "lcd.h"
#include "wifi.h"

rt_device_t lcd_dev;
static struct rt_semaphore lcd_sem;
static uint8_t rx_buffer[128];  // 扩大缓冲区
static rt_size_t rx_len = 0;
static uint8_t cmd_buffer[32];  // 命令缓冲区
static rt_size_t cmd_len = 0;

// 存储SSID和密码的字符串
char ssid_str[64];
char pwd_str[64];
extern int up_period;

/* 数据发送线程控制变量 */
static int data_send_running = 0;  // 数据发送线程运行标志

/* 线程优先级、栈大小和线程控制块定义 */
#define LCD_CMD_THREAD_PRIORITY       21
#define LCD_CMD_THREAD_STACK_SIZE     2048
#define LCD_CMD_THREAD_TIMESLICE      10

#define DATA_SEND_THREAD_PRIORITY     22  // 数据发送线程优先级
#define DATA_SEND_THREAD_STACK_SIZE   1024
#define DATA_SEND_THREAD_TIMESLICE    5

#define MAX_RECORDS 100       // 最大记录数
#define RECORD_LENGTH 50      // 每条记录最大长度

// 定义LCD指令
const uint8_t LCD_SYNC_CMD[5] = {0x04, 0xFF, 0xFF, 0xFF, 0x16};
const uint8_t get_loca_CMD[2] = {0xf1, 0xf2};  // 获取位置记录指令
const uint8_t get_env_CMD[2] = {0xf1, 0xf1};   // 获取环境数据指令

const uint8_t set_ssid_CMD[2] = {0x12, 0x11};    // SSID开始
const uint8_t set_pasd_CMD[2] = {0x12, 0x12};    // 密码开始
const uint8_t set_period_CMD[2] = {0x12, 0x13};  // 周期开始
const uint8_t end_CMD[2] = {0x12, 0x14};         // 结束标记

// 新增控制指令
const uint8_t START_SEND_CMD[2] = {0x12, 0x21};  // 开始发送数据
const uint8_t STOP_SEND_CMD[2] = {0x12, 0x22};   // 停止发送数据

extern int adc_data[3];
extern rt_uint8_t temperature, temperature_x, humidity, humidity_x;
extern char record_env_array[MAX_RECORDS][RECORD_LENGTH];
extern char record_gps_array[MAX_RECORDS][RECORD_LENGTH];
extern rt_uint8_t sw420_intensity;
extern uint16_t valid_record_count;
extern char lat_string[32];  // 纬度字符串数组
extern char lon_string[32];  // 经度字符串数组

/* 函数声明 */
void send_all_data(void);

/* 串口屏接收回调 */
static rt_err_t lcd_rx_callback(rt_device_t dev, rt_size_t size)
{
    rt_sem_release(&lcd_sem);
    return RT_EOK;
}

/* 发送数据到LCD */
static void send_lcd_data(int test_data)
{
    char cmd[32];
    snprintf(cmd, sizeof(cmd), "test.val=%d\xff\xff\xff", test_data);
    rt_device_write(lcd_dev, 0, cmd, strlen(cmd));
    rt_kprintf("Sent test data to LCD\n");
}
extern uint16_t year;
extern uint8_t month, day, hour, minute, second;
/* 发送time信息到串口屏 */
void lcd_time_sys(void)
{
    char cmd_buffer[64];
    rt_size_t len;
    if (lcd_dev == RT_NULL) {
        rt_kprintf("UART0 device not initialized!\n");
        return;
    }
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "year=%d\xff\xff\xff", 2025);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);

    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "month=%d\xff\xff\xff",7);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);

    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "day=%d\xff\xff\xff",9);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);

    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "hour=%d\xff\xff\xff",23);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);

    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "minute=%d\xff\xff\xff", 15);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);

    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "second=%d\xff\xff\xff", 0);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);
}
/* 发送数据到串口屏 */
void send_to_serial_screen(void)
{
    char cmd_buffer[64];
    rt_size_t len;

    if (lcd_dev == RT_NULL) {
        rt_kprintf("UART0 device not initialized!\n");
        return;
    }
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "hum=%d\xff\xff\xff", humidity);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "temper=%d\xff\xff\xff", temperature);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "temper_x=%d\xff\xff\xff", temperature_x);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "sw420=%d\xff\xff\xff", sw420_intensity);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);
    //经纬度发送
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "wenshi.lot.txt=\"%s\"\xff\xff\xff", lon_string);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "wenshi.lat.txt=\"%s\"\xff\xff\xff", lat_string);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);
}
/* 发送数据到串口屏 */
void lcd_wire_statue(rt_bool_t flag1,rt_bool_t flag2)
{
    char cmd_buffer[64];
    rt_size_t len;
    if (lcd_dev == RT_NULL) {
        rt_kprintf("UART0 device not initialized!\n");
        return;
    }
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "wififlag=%d\xff\xff\xff", flag1);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);

    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "mqttflag=%d\xff\xff\xff", flag2);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);
}
void lcd_power_statue(void);
/* 发送power信息到串口屏 */
void lcd_power_statue(void)
{
    char cmd_buffer[64];
    rt_size_t len;
    if (lcd_dev == RT_NULL) {
        rt_kprintf("UART0 device not initialized!\n");
        return;
    }
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "bat=%d\xff\xff\xff", adc_data[1]*95);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);

    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "power=%d\xff\xff\xff", adc_data[0]+2);
    rt_device_write(lcd_dev, 0, cmd_buffer, len);
    rt_thread_mdelay(50);
}

void send_gps_data();
void send_evn_data();
void cmd_start_time_sync();
/* 解析命令类型 */
static void parse_command(void)
{
    // 检查是否匹配LCD_SYNC_CMD指令
    if (rx_len == sizeof(LCD_SYNC_CMD) &&
        memcmp(rx_buffer, LCD_SYNC_CMD, sizeof(LCD_SYNC_CMD)) == 0) {
        rt_kprintf("LCD sync command received\n");
        cmd_start_time_sync();
        lcd_time_sys();
        rx_len = 0;
        return;
    }

    // 检查是否匹配get_loca_CMD指令
    if (rx_len >= sizeof(get_loca_CMD) &&
        memcmp(rx_buffer, get_loca_CMD, sizeof(get_loca_CMD)) == 0) {
        rt_kprintf("gps cmd rec\n");
        send_gps_data();
        rx_len = 0;
        return;
    }

    // 检查是否匹配get_env_CMD指令
    if (rx_len >= sizeof(get_env_CMD) &&
        memcmp(rx_buffer, get_env_CMD, sizeof(get_env_CMD)) == 0) {
        rt_kprintf("env cmd rec \n");
        send_evn_data();
        rx_len = 0;
        return;
    }

    // 检查是否匹配set_period_CMD指令
    if (rx_len >= sizeof(set_period_CMD) + 1 &&
        memcmp(rx_buffer, set_period_CMD, sizeof(set_period_CMD)) == 0) {
        up_period = rx_buffer[sizeof(set_period_CMD)];
        rt_kprintf("Set period command received, value: %d\n", up_period);
        rx_len = 0;
        return;
    }

    // 检查是否匹配开始发送指令
    if (rx_len >= sizeof(START_SEND_CMD) &&
        memcmp(rx_buffer, START_SEND_CMD, sizeof(START_SEND_CMD)) == 0) {
        rt_kprintf("sending\n");
        data_send_running = 1;
        rx_len = 0;
        return;
    }

    // 检查是否匹配停止发送指令
    if (rx_len >= sizeof(STOP_SEND_CMD) &&
        memcmp(rx_buffer, STOP_SEND_CMD, sizeof(STOP_SEND_CMD)) == 0) {
        rt_kprintf("Stop\n");
        data_send_running = 0;
        rx_len = 0;
        return;
    }

    // 保持缓冲区长度不超过最大指令长度+1
    if (rx_len > sizeof(LCD_SYNC_CMD) + 1) {
        memmove(rx_buffer, rx_buffer + 1, rx_len - 1);
        rx_len--;
    }
}

/* 解析数据包 */
static void parse_packet(void)
{
    rt_size_t pos = 0;
    while (pos < rx_len) {
        // 查找SSID开始标志
        if (pos + 2 <= rx_len && rx_buffer[pos] == 0x12 && rx_buffer[pos+1] == 0x11) {
            pos += 2;
            rt_size_t ssid_start = pos;

            // 查找密码开始标志
            while (pos + 2 <= rx_len && !(rx_buffer[pos] == 0x12 && rx_buffer[pos+1] == 0x12)) {
                pos++;
            }
            if (pos + 2 > rx_len) break;

            // 提取SSID
            rt_size_t ssid_len = pos - ssid_start;
            memcpy(ssid_str, rx_buffer + ssid_start, ssid_len);
            ssid_str[ssid_len] = '\0';
            rt_kprintf("SSID: %s\n", ssid_str);

            pos += 2;
            rt_size_t pwd_start = pos;

            // 查找周期开始标志
            while (pos + 2 <= rx_len && !(rx_buffer[pos] == 0x12 && rx_buffer[pos+1] == 0x13)) {
                pos++;
            }
            if (pos + 2 > rx_len) break;

            // 提取密码
            rt_size_t pwd_len = pos - pwd_start;
            memcpy(pwd_str, rx_buffer + pwd_start, pwd_len);
            pwd_str[pwd_len] = '\0';
            rt_kprintf("Password: %s\n", pwd_str);

            pos += 2;
            rt_size_t period_start = pos;

            // 查找结束标志
            while (pos + 2 <= rx_len && !(rx_buffer[pos] == 0x12 && rx_buffer[pos+1] == 0x14)) {
                pos++;
            }
            if (pos + 2 > rx_len) break;

            // 提取周期
            if (period_start < pos) {
                up_period = rx_buffer[period_start];
                rt_kprintf("Period: %d\n", up_period);
            }

            pos += 2;
            // 移除已处理的数据
            memmove(rx_buffer, rx_buffer + pos, rx_len - pos);
            rx_len -= pos;
            pos = 0; // 重新开始查找
            //如果执行完了 就断开wifi连接
            //放在此处
            reconnect_wifi();
        }
        else {
            pos++;
        }
    }
}

/* 处理LCD指令的线程 */
static void lcd_cmd_thread(void *arg)
{
    uint8_t byte;
    while (1) {
        rt_sem_take(&lcd_sem, RT_WAITING_FOREVER);

        // 读取所有接收数据
        while (rt_device_read(lcd_dev, 0, &byte, 1) == 1) {
            if (rx_len < sizeof(rx_buffer)) {
                rx_buffer[rx_len++] = byte;
            } else {
                rx_len = 0; // 缓冲区溢出
            }
        }

        // 先尝试解析命令
        parse_command();

        // 再尝试解析数据包
        parse_packet();
    }
}

/* 数据发送线程 */
static struct rt_semaphore data_send_sem;  // 数据发送信号量

static void data_send_thread(void *arg)
{
    while (1) {
        // 如果运行标志为0，则等待
        if (data_send_running)
        {
            // 发送数据到串口屏
            send_to_serial_screen();
            // 延时一段时间
            rt_thread_mdelay(up_period * 100);
        }
        else{
                //刷新电量信息
                lcd_power_statue();
                rt_thread_mdelay(1000);  // 以100ms为单位
            }
        }
}

/* 初始化函数 */
int uart_init(void)
{
    rt_err_t ret;
    lcd_dev = rt_device_find(LCD_UART);
    if (!lcd_dev) {
        LOG_E(" LCD UART device not found\n");
        return RT_ERROR;
    }

    // 初始化LCD命令线程信号量
    rt_sem_init(&lcd_sem, "lcd_sem", 0, RT_IPC_FLAG_FIFO);

    // 初始化数据发送线程信号量
    rt_sem_init(&data_send_sem, "data_send_sem", 0, RT_IPC_FLAG_FIFO);

    rt_device_open(lcd_dev, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_STREAM);
    rt_device_set_rx_indicate(lcd_dev, lcd_rx_callback);

    /* 创建LCD命令线程 */
    rt_thread_t cmd_thread = rt_thread_create("lcd_cmd", lcd_cmd_thread, RT_NULL,
                                          LCD_CMD_THREAD_STACK_SIZE,
                                          LCD_CMD_THREAD_PRIORITY,
                                          LCD_CMD_THREAD_TIMESLICE);
    if (cmd_thread) {
        rt_thread_startup(cmd_thread);
        LOG_I("LCD init successfully");
    } else {
        LOG_E("Failed to create LCD command thread");
        return RT_ERROR;
    }

    /* 创建数据发送线程 */
    rt_thread_t send_thread = rt_thread_create("lcd_ex", data_send_thread, RT_NULL,
                                          DATA_SEND_THREAD_STACK_SIZE,
                                          DATA_SEND_THREAD_PRIORITY,
                                          DATA_SEND_THREAD_TIMESLICE);
    if (send_thread) {
        rt_thread_startup(send_thread);
        LOG_I("lcd send thread start");
    } else {
        LOG_E("Failed to create data send thread");
        return RT_ERROR;
    }

    return RT_EOK;
}

void send_evn_data(void)
{
    char cmd_buffer[512];
    rt_size_t len;

    if (lcd_dev == RT_NULL) {
        LOG_E("LCD device not initialized!");
        return;
    }

    LOG_I("get %d records", valid_record_count);

    // 构建命令头部
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "record.g0.txt=\"");
    if (len >= sizeof(cmd_buffer)) {
        LOG_E("Error: Command buffer overflow (header)");
        return;
    }

    // 拼接所有record_array中的字符串
    for (uint16_t i = 0; i < valid_record_count; i++) {
        // 计算剩余空间
        size_t remaining = sizeof(cmd_buffer) - strlen(cmd_buffer);

        // 拼接空格和下一个字符串
        len = snprintf(cmd_buffer + strlen(cmd_buffer), remaining, "%s\\r", record_env_array[i]);
        if (len >= remaining) {
            rt_kprintf("Error: Command buffer overflow at record %d\n", i);
            break;
        }
    }

    // 添加终止符\xFF
    len = strlen(cmd_buffer);
    if (len + 4 < sizeof(cmd_buffer)) {  // 确保有足够空间添加3个\xFF
        cmd_buffer[len++] = '\"';
        cmd_buffer[len++] = '\xFF';
        cmd_buffer[len++] = '\xFF';
        cmd_buffer[len++] = '\xFF';
        cmd_buffer[len] = '\0';  // 保持C字符串完整性（可选）

        // 发送完整命令
        rt_device_write(lcd_dev, 0, cmd_buffer, len);
    } else {
        rt_kprintf("Error: No space for terminators\n");
    }
}

void send_gps_data(void)
{
    char cmd_buffer[1024];
    rt_size_t len;

    if (lcd_dev == RT_NULL) {
        LOG_E("LCD device not initialized!\n");
        return;
    }

    LOG_I("get %d records", valid_record_count);

    // 构建命令头部
    len = snprintf(cmd_buffer, sizeof(cmd_buffer), "locdcod.g0.txt=\"");
    if (len >= sizeof(cmd_buffer)) {
        rt_kprintf("Error: Command buffer overflow (header)\n");
        return;
    }

    // 拼接所有record_array中的字符串
    for (uint16_t i = 0; i < valid_record_count; i++) {
        // 计算剩余空间
        size_t remaining = sizeof(cmd_buffer) - strlen(cmd_buffer);

        // 拼接空格和下一个字符串
        len = snprintf(cmd_buffer + strlen(cmd_buffer), remaining, "%s\\r", record_gps_array[i]);
        if (len >= remaining) {
            rt_kprintf("Error: Command buffer overflow at record %d\n", i);
            break;
        }
    }

    // 添加终止符\xFF
    len = strlen(cmd_buffer);
    if (len + 4 < sizeof(cmd_buffer)) {  // 确保有足够空间添加3个\xFF
        cmd_buffer[len++] = '\"';
        cmd_buffer[len++] = '\xFF';
        cmd_buffer[len++] = '\xFF';
        cmd_buffer[len++] = '\xFF';
        cmd_buffer[len] = '\0';  // 保持C字符串完整性（可选）

        // 发送完整命令
        rt_device_write(lcd_dev, 0, cmd_buffer, len);
    } else {
        rt_kprintf("Error: No space for terminators\n");
    }
}


// MSH命令
MSH_CMD_EXPORT(send_to_serial_screen, test);
INIT_DEVICE_EXPORT(uart_init);
INIT_APP_EXPORT(cmd_start_time_sync);
